package com.graph.base;

import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.NoSuchElementException;
import java.util.Set;

public class VertexImpl implements VertexInterface, java.io.Serializable {
	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;
	/**
	 * 点的名称
	 */
	private String name;
	/**
	 * 对应这个连向的边
	 */
	private List<Edge> edgeList;
	/**
	 * 是否访问过(用于广度遍历<局部中心算法>)
	 */
	private boolean visited;
	/**
	 * 是否为中心点(<局部中心算法>)
	 */
	private Boolean isCentralNodes=false;
	/**
	 * 当前点离开始点的距离(用于广度遍历<局部中心算法>)
	 */
	private double cost;
	/**
	 * 每个点的度数
	 */
	private Integer degree;
	/**
	 * 概率模体算法另外实用的一套编号
	 */
	private Integer reNumber;
	/**
	 * 当前点的密度
	 */
	private double density;
	
	/**
	 * 当前点是否已经被选入某个社区
	 */
	private boolean isSelected;
	
	private Set<VertexInterface> neighors;
	@Override
	public Set<VertexInterface> getNeighors() {
		return neighors;
	}

    @Override
	public void setNeighors(Set<VertexInterface> neighors) {
		this.neighors = neighors;
	}


	@Override
	public List<Edge> getEdgeList() {
		return edgeList;
	}

	
	@Override
	public double getCost() {
		return cost;
	}
    @Override
	public void setCost(double cost) {
		this.cost = cost;
	}
	
	@Override
	public void addEdgeBetweenness(String name, Integer weight) {
		for (Edge edge : edgeList) {
			if(edge.getEndVertex().getName().equals(name)){
				edge.setBetweenness(edge.getBetweenness()+weight);
			};
		}
	}

	public VertexImpl(String vertexLabel) {
		setName(vertexLabel);
		edgeList = new LinkedList<Edge>();// 是Vertex的属性,说明每个顶点都有一个edgeList用来存储所有与该顶点关系的边
		visited = false;
	}

	private class NeighborIterator implements Iterator<VertexInterface> {

		Iterator<Edge> edgesIterator;

		private NeighborIterator() {
			edgesIterator = edgeList.iterator();// 获得遍历edgesList 的迭代器
		}

		@Override
		public boolean hasNext() {
			return edgesIterator.hasNext();
		}

		@Override
		public VertexInterface next() {
			VertexInterface nextNeighbor = null;
			if (edgesIterator.hasNext()) {
				Edge edgeToNextNeighbor = edgesIterator.next();// LinkedList中存储的是Edge
				nextNeighbor = edgeToNextNeighbor.getEndVertex();// 从Edge对象中取出顶点
			} else{
				throw new NoSuchElementException();
			}
			return nextNeighbor;
		}

		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}
	}

	private class WeightIterator implements Iterator<Edge> {

		private Iterator<Edge> edgesIterator;
		private WeightIterator() {
			edgesIterator = edgeList.iterator();
		}
		@Override
		public boolean hasNext() {
			return edgesIterator.hasNext();
		}
		@Override
		public void remove() {
			throw new UnsupportedOperationException();
		}
		@Override
		public Edge next() {
			return edgesIterator.next();
		}

	}

	@Override
	public void visit() {
		this.visited = true;
	}

	@Override
	public void unVisit() {
		this.visited = false;
	}

	@Override
	public boolean isVisited() {
		return visited;
	}

	@Override
	public boolean connect(VertexInterface endVertex, Integer edgeWeight) {
		boolean result = false;
		if (!this.equals(endVertex)) {
			Iterator<VertexInterface> neighbors = this
					.getNeighborInterator();
			boolean duplicateEdge = false;
			while (!duplicateEdge && neighbors.hasNext()) {
				VertexInterface nextNeighbor = neighbors.next();
				if (endVertex.equals(nextNeighbor)) {
					duplicateEdge = true;
					break;
				}
			}
			if (!duplicateEdge) {
				edgeList.add(new Edge(endVertex, edgeWeight));
				result = true;
			}
		}
		return result;
	}

	@Override
	public boolean connect(VertexInterface endVertex) {
		return connect(endVertex, 0);
	}

	@Override
	public Iterator<VertexInterface> getNeighborInterator() {
		return new NeighborIterator();
	}

	@Override
	public Iterator<Edge> getWeightIterator() {
		return new WeightIterator();
	}

	@Override
	public boolean hasNeighbor() {
		return !(edgeList.isEmpty());
	}

	@Override
	public VertexInterface getUnvisitedNeighbor() {
		VertexInterface result = null;
		Iterator<VertexInterface> neighbors = getNeighborInterator();
		while (neighbors.hasNext() && result == null) {// 获得该顶点的第一个未被访问的邻接点
			VertexInterface nextNeighbor = neighbors.next();
			if (!nextNeighbor.isVisited()){
				result = nextNeighbor;
			}

		}
		return result;
	}
	
	// 判断两个顶点是否相同
	@Override
	public boolean equals(Object other) {
		boolean result;
		if ((other == null) || (getClass() != other.getClass())){
			result = false;
		}
		else {
			VertexImpl otherVertex = (VertexImpl) other;
			result = name.equals(otherVertex.name);// 节点是否相同最终还是由标识
													// 节点类型的类的equals() 决定
		}
		return result;
	}

	@Override
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	@Override
	public Boolean getIsCentralNodes() {
		return isCentralNodes;
	}
	@Override
	public void setIsCentralNodes(Boolean isCentralNodes) {
		this.isCentralNodes = isCentralNodes;
	}
	@Override
	public int compareTo(Object o) {
		return 0;
	}
	@Override
	public Integer getDegree() {
		if(degree==null){
			degree=this.getEdgeList().size();
		}
		return degree;
	}
	@Override
	public void setDegree(Integer degree) {
		this.degree = degree;
	}
	@Override
	public Integer getReNumber() {
		return reNumber;
	}
	@Override
	public void setReNumber(Integer reNumber) {
		this.reNumber = reNumber;
	}

    @Override
	public double getDensity() {
		return density;
	}

    @Override
	public void setDensity(double density) {
		this.density = density;
	}

    @Override
	public boolean isSelected() {
		return isSelected;
	}

    @Override
	public void setSelected(boolean isSelected) {
		this.isSelected = isSelected;
	}

}